package ywpt.service.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;

import ywpt.components.acegi.domain.Function;
import ywpt.components.acegi.domain.Resource;
import ywpt.components.acegi.domain.Role;
import ywpt.core.dao.extend.HibernateEntityExtendDao;
import ywpt.core.exception.UniqueConstraintException;

/**
 * 
 * 系统功能服务实现类 2007-10-8 下午09:57:23
 * 
 * @author <a href="mailto:mrwyxster@gmail.com">Oliver Wen</a>
 * 
 */
@Service("functionService")
public class FunctionServiceImpl extends HibernateEntityExtendDao<Function> implements FunctionService {
	public FunctionServiceImpl() {
	}

	public Function getFunctionById(Long id) {
		return this.get(id);
	}

	public List<Function> getAllFunctions() {
		return this.getAll();
	}

	@SuppressWarnings("unchecked")
	public List<Function> getFunctions(DetachedCriteria query) {
		return this.findAllByCriteria(query);
	}

	@SuppressWarnings("unchecked")
	public List<Function> getFunctions(DetachedCriteria query, int pageSize, int startIndex) {
		return this.findAllByCriteria(query, pageSize, startIndex);
	}

	public int getFunctionsCount(DetachedCriteria query) {
		return this.getCountByCriteria(query);
	}

	public void saveFunction(Function func) {
		try {
			this.save(func);
		} catch (DataIntegrityViolationException e) {
			throw new UniqueConstraintException("Function '" + func.getFunctionName() + "' already exists!");
		}
	}

	public void updateFunction(Function func) {
		this.update(func);
	}

	public void removeFunction(String id) {
		this.removeById(new Long(id));
	}

	public Function getFunctionByFunctionName(String functionName) {
		return this.findUniqueBy("functionName", functionName);
	}

	public void addRoles(Function func, List<Long> roles) {
		if (roles != null && roles.size() > 0) {
			func.setRoles(new HashSet<Role>(0));
			for (int i = 0, j = roles.size(); i < j; i++) {
				Role role = (Role) this.get(Role.class, roles.get(i));
				func.getRoles().add(role);
			}
			super.update(func);
		}
	}

	public int[] removeRoles(Function func, Long[] ids) {
		for (int i = 0; i < ids.length; i++) {
			Role role = super.get(Role.class, ids[i]);
			func.getRoles().remove(role);
		}
		super.update(func);
		int results[] = new int[ids.length];
		for (int i = 0; i < ids.length; i++) {
			results[i] = 1;
		}
		return results;
	}

	@SuppressWarnings("unchecked")
	public List getFunctionTree(Long parentId, List roles) {
		StringBuffer rolesSet = new StringBuffer("");
		String hql = "";
		boolean isAdmin = false;
		for (int i = 0; i < roles.size(); i++) {
			Role role = (Role) roles.get(i);
			if (role.getRoleName().equals("ROLE_ADMIN")) {
				isAdmin = true;
			}
			rolesSet.append(role.getId());
			rolesSet.append(",");
		}
		rolesSet.append(0L);
		if (!isAdmin) {
			hql = "select distinct f from ywpt.components.acegi.domain.Function as f left join f.roles as role";
			if (parentId != null) {
				hql = hql + " where f.parent.id=" + parentId;
			} else {
				hql = hql + " where f.parent.id is null";
			}
			hql = hql + " and role.id in(" + rolesSet.toString() + ")";
		} else {
			hql = "select f from ywpt.components.acegi.domain.Function as f";
			if (parentId != null) {
				hql = hql + " where f.parent.id=" + parentId;
			} else {
				hql = hql + " where f.parent.id is null";
			}
		}
		// Query q =this.getSession().createQuery(hql);
		// q.setResultTransformer(Transformers.aliasToBean(Function.class));
		List<Function> childList = super.find(hql);
		List jsonList = new ArrayList();
		for (int i = 0; i < childList.size(); i++) {
			Function row = (Function) childList.get(i);
			String permissions = this.getPermissions(row.getFunctionCode(), roles);
			Map child = new HashMap();
			child.put("text", row.getFunctionName());
			child.put("id", row.getId());
			List grandChildRow = getFunctionTree(row.getId(), roles);
			if (grandChildRow.size() != 0) {
				child.put("children", grandChildRow);
			} else {
				child.put("leaf", Boolean.TRUE);
				child.put("url", row.getUrl());
				child.put("iconCls", "tree-node");
				child.put("code", row.getFunctionCode());
				child.put("operations", permissions);
			}
			jsonList.add(child);
		}
		return jsonList;
	}

	@SuppressWarnings("unchecked")
	public List getFunctionTree(Long parentId) {
		String hql = "from ywpt.components.acegi.domain.Function as f";
		if (parentId != null) {
			hql = hql + " where f.parent.id=" + parentId;
		} else {
			hql = hql + " where f.parent.id is null";
		}
		List<Function> childList = super.find(hql);
		List jsonList = new ArrayList();
		for (int i = 0; i < childList.size(); i++) {
			Function row = childList.get(i);
			Map child = new HashMap();
			child.put("text", row.getFunctionName());
			child.put("id", row.getId());
			List grandChildRow = getFunctionTree(row.getId());
			if (grandChildRow.size() != 0) {
				child.put("children", grandChildRow);
			} else {
				child.put("leaf", Boolean.TRUE);
				child.put("url", row.getUrl());
				child.put("iconCls", "tree-node-leaf");
				child.put("code", row.getFunctionCode());
			}
			jsonList.add(child);
		}
		return jsonList;
	}

	@SuppressWarnings("unchecked")
	protected String getPermissions(String functionCode, List roles) {
		StringBuffer permissions = new StringBuffer("");
		String hql = "select res from ywpt.components.acegi.domain.Resource res left join res.roles role where res.functionCode='" + functionCode + "'";
		hql = hql + " and (";
		if (roles.size() > 0) {
			for (Iterator itr = roles.iterator(); itr.hasNext();) {
				Role r = (Role) itr.next();
				if (r.getRoleName().equals("ROLE_ADMIN")) {
					return "add|edit|delete|print|check|read";
				} else {
					hql = hql + "role.id=" + r.getId() + " or ";
				}
			}
		}
		hql = hql + " 1=2)";
		List list = super.find(hql);
		for (Iterator sItr = list.iterator(); sItr.hasNext();) {
			Resource res = (Resource) sItr.next();
			permissions.append(res.getResString());
			if (sItr.hasNext()) {
				permissions.append("|");
			}
		}
		return permissions.toString();
	}

	@Override
	protected void onValid(Function entity) {
		if (!isUnique(entity, "functionCode")) {
			throw new UniqueConstraintException("功能编号" + entity.getFunctionCode() + "重复");
		}
	}
}